<!--
*@Author: QWP
*@Description: 树形
*@Date: 2024-07-09 18:06:45
-->
<template>
  <a-layout class="f-h-100">
    <a-layout-header style="background: #fff; padding: 0; line-height: unset; height: max-content">
      <div class="u-tree-title f-padding-r30" v-if="title">{{  title  }}</div>
      <a-input-search v-model:value="searchValue" 
        v-if="showSearch"
        style="margin-bottom: 8px;" 
        :class="{'f-padding-r30': !title,'f-padding-r12': title}"
        placeholder="搜索关键字" />
    </a-layout-header>
    <a-layout-content style="overflow: auto; background-color: #fff">
      <Tree v-bind="filterProps($attrs)"
        v-model:checkedKeys="checkedKeys1"
        v-model:expandedKeys="expandedKeys1"
        :auto-expand-parent="autoExpandParent"
        :fieldNames="fieldNames"
        @check="treeCheck"
        @expand="expand">
        <template #title="item">
          <span v-if="title.indexOf(searchValue) > -1 && showSearch">
            {{ item[fieldNames.title].substring(0, [fieldNames.title].indexOf(searchValue)) }}
            <span style="color: #f50">{{ searchValue }}</span>
            {{ item[fieldNames.title].substring([fieldNames.title].indexOf(searchValue) + searchValue.length) }}
          </span>
          <span v-else>{{ item[fieldNames.title] }}</span>
        </template>
      </Tree>
    </a-layout-content>
  </a-layout>
</template>

<script lang='ts' setup>
defineOptions({
  name: 'u-tree'
})
import { Tree } from "ant-design-vue";
import { ref, reactive, computed, onMounted, useAttrs, watch, onUnmounted } from 'vue' 
import { useRoute, useRouter } from 'vue-router'
import { isRefC } from '@/util/common'
import { cloneDeep } from 'lodash'

interface Props {
  title?: string,
  showSearch?: boolean,
  fieldNames?: {},
  expandedKeys?: any,
  checkedKeys?: any,
}
const props = withDefaults(defineProps<Props>(), {
  showSearch: true,
  title: '',
  fieldNames: { title: 'label', key: 'value', children: 'children' },
  expandedKeys: [],
  checkedKeys: [],
})

const attrs = useAttrs();

const emits = defineEmits(['expand', 'check', 'update:expandedKeys', 'update:checkedKeys', 'change', 'update:pagination'])

const searchValue = ref<string>('')
const autoExpandParent = ref<boolean>(true);
let checkedKeys1 = ref<(string | number)[]>([]);
let expandedKeys1 = ref<(string | number)[]>([]);

// 过滤掉重复的绑定元素
const filterProps = (attrs1) => {
  let tAttrs = cloneDeep(attrs1);
  delete tAttrs['onCheck']
  return tAttrs
}

// 扁平树形数据
let flatTreeData: TreeProps['treeData'] = [];
const flatTree = (data: TreeProps['treeData']): void => {
  data.forEach(item => {
    const key = item.key;
    flatTreeData.push({ key, title: key });
    if (item.children) {
      flatTree(item.children);
    }
  })
}

// 搜索树形数据
const filterTree = (data: TreeProps['treeData']): void => {
  const expanded = flatTreeData
    .map((item: TreeProps['treeData'][number]) => {
      if (item.title.indexOf(value) > -1) {
        return getParentKey(item.key, gData.value);
      }
      return null;
    })
    .filter((item, i, self) => item && self.indexOf(item) === i);
  expandedKeys.value = expanded;
  searchValue.value = value;
  autoExpandParent.value = true;
}

// 选择事件
const treeCheck = (keys, { checked, checkedNodes, node, event }) => {
  emits('update:checkedKeys', keys)
  emits('check', keys, { checked, checkedNodes, node, event })
}

// 展开事件
const expand = (expandedKeys, {expanded: bool, node}) => {
  emits('update:expandedKeys', expandedKeys)
  emits('expand', expandedKeys, {expanded: bool, node})
}

watch(() => searchValue, value => {
  filterTree();
});

watch(() => attrs, (nval, oval) => {
  let treeData = [];
  if(attrs['treeData']) {
    treeData = attrs['treeData'];
  }
  else if(attrs['tree-data']) {
    treeData = attrs['tree-data'];
  }
  flatTree(treeData)
}, { deep: true, immediate: true })

watch(() => props.expandedKeys, (nval, oval) => {
  expandedKeys1.value = isRefC(nval) ?? []
}, { deep: true, immediate: true })

watch(() => props.checkedKeys, (nval, oval) => {
  checkedKeys1.value = isRefC(nval) ?? []
}, { deep: true, immediate: true })

</script>

<style lang='scss'>
.u-tree-title{
  height: 40px;
  line-height: 40px;
  font-family: PingFang SC Medium, PingFang SC Medium;
  font-weight: 400;
  font-size: 16px;
  color: #333333;
  text-align: left;
  font-style: normal;
  text-transform: none;
}
</style>